package com.softserve.crazymachine.configurator;

import java.util.*;
import java.util.Map.Entry;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

	class CustomMapConverter implements Converter {

	private HierarchicalStreamReader customReader=null;
	private UnmarshallingContext customContext=null;
	
    public boolean canConvert(Class clazz) {
        return AbstractMap.class.isAssignableFrom(clazz);
    }

   
	public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {

    	Map<String,String> map = (HashMap<String,String>) value;
        for (Object obj : map.entrySet()) {
            Entry entry = (Entry) obj;
            
            writer.startNode(entry.getKey().toString());
            if(AbstractMap.class.isAssignableFrom(entry.getValue().getClass())){
            	Map<String,String> tmap=(HashMap<String,String>) entry.getValue();
            	
            	Set set = tmap.entrySet();
            	Iterator i = set.iterator();
            	while(i.hasNext()){
                  Map.Entry me = (Map.Entry)i.next();
                  writer.startNode(me.getKey().toString());
                  writer.setValue(me.getValue().toString());
                  writer.endNode();
                }
              
            }else{
            	writer.setValue(entry.getValue().toString());
            }
            
            writer.endNode();
             
        }
    }

    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    	
    	 Map<String, Object> map = new HashMap<String, Object>();
    	 this.customReader=reader;
    	 this.customContext=context;
    	 String attKey=null;
    	    while(this.customReader.hasMoreChildren()) {
    	    	
    	    	this.customReader.moveDown();
    	    	if (this.customReader.hasMoreChildren()) {
    	    		
    	    		Map<String, Object> tmap = null ;
    	    		 attKey=this.customReader.getNodeName();
    	    		tmap=(HashMap<String, Object>) this.unmarshal(this.customReader, this.customContext);
    	    			if(!tmap.isEmpty()){
    	    			map.put(attKey, tmap);
    	    			}
    	    	}else{    	    			
            	map.put(this.customReader.getNodeName(), this.customReader.getValue());
    	    		
            	}
    	    	this.customReader.moveUp();
    	    }
    	    return map;
    }


}
